package com.jhgsys.internal.common.utils;

import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

/**
 * 图片操作帮助类
 *
 * @author Dongs
 *
 */
public class ImageUtils {
	/**
	 * 剪切图片,没有处理图片后缀名是否正确,还有gif动态图片
	 *
	 * @param sourcePath
	 *            源路径(包含图片)
	 * @param targetPath
	 *            目标路径 null则默认为源路径
	 * @param x
	 *            起点x坐标
	 * @param y
	 *            起点y左边
	 * @param width
	 *            剪切宽度
	 * @param height
	 *            剪切高度
	 * @return 目标路径
	 * @throws IOException
	 *             if sourcePath image doesn't exist
	 */
	public static String cutImage(String sourcePath, String targetPath, int x,
			int y, int width, int height) throws IOException {
		File imageFile = new File(sourcePath);
		if (!imageFile.exists()) {
			throw new IOException("Not found the images:" + sourcePath);
		}
		if (targetPath == null || targetPath.isEmpty()) {
			targetPath = sourcePath;
		}
		String format = sourcePath.substring(sourcePath.lastIndexOf(".") + 1
                                            );
		BufferedImage image = ImageIO.read(imageFile);
		image = image.getSubimage(x, y, width, height);
		ImageIO.write(image, format, new File(targetPath));
		return targetPath;
	}

	/**
	 * 压缩图片
	 *
	 * @param sourcePath
	 *            源路径(包含图片)
	 * @param targetPath
	 *            目标路径 null则默认为源路径
	 * @param width
	 *            压缩后宽度
	 * @param height
	 *            压缩后高度
	 * @return 目标路径
	 * @throws IOException
	 *             if sourcePath image does not exist
	 */
	public static String zoomImage(String sourcePath, String targetPath,
			int width, int height) throws IOException {
		File imageFile = new File(sourcePath);
		if (!imageFile.exists()) {
			throw new IOException("Not found the images:" + sourcePath);
		}
		if (targetPath == null || targetPath.isEmpty()) {
			targetPath = sourcePath;
		}

		File dir = new File(targetPath);
		// 判断文件夹是否存在
		if (!dir.getParentFile().exists()) {
			dir.getParentFile().mkdirs();
		}
		String format = sourcePath.substring(sourcePath.lastIndexOf(".") + 1
                                            );

		Image src=Toolkit.getDefaultToolkit().getImage(imageFile.getPath());
		src.flush();
		BufferedImage image=toBufferedImage(src);

//		BufferedImage image = ImageIO.read(imageFile);
		// 临时宽度
		int tempWidth = 0;
		// 临时高度
		int tempHeight = 0;
		// 没传值的情况下默认压缩成1000宽度分辨率
		if (width == 0 && height == 0) {
			tempWidth = 1000;
			tempHeight = 1000;
		} else if (width != 0 && height == 0) {
			tempWidth = width;
			tempHeight = width * image.getHeight() / image.getWidth();
		} else if (width == 0 && height != 0) {
			tempWidth = height * image.getWidth() / image.getHeight();
			tempHeight = height;
		} else {
			tempWidth = width;
			tempHeight = height;
		}
		//只有大图才压缩
		if (tempWidth < image.getWidth() || tempHeight < image.getHeight()) {
			image = zoom(image, tempWidth, tempHeight);
			ImageIO.write(image, format, new File(targetPath));
		} else {
			if (targetPath == sourcePath || targetPath.equals(sourcePath)) {
				//相同文件不做处理
			} else {
				ImageIO.write(image, format, new File(targetPath));
			}
		}

		return targetPath;
	}

	/**
	 * 压缩图片
	 *
	 * @param sourceImage
	 *            待压缩图片
	 * @param width
	 *            压缩图片高度
	 * @param height
	 *            压缩图片宽度
	 */
	private static BufferedImage zoom(BufferedImage sourceImage, int width,
			int height) {
		BufferedImage zoomImage = new BufferedImage(width, height,
				sourceImage.getType());
		Image image = sourceImage.getScaledInstance(width, height,
				Image.SCALE_SMOOTH);
		Graphics gc = zoomImage.getGraphics();
		gc.setColor(Color.WHITE);
		gc.drawImage(image, 0, 0,width,height,Color.white, null);
		return zoomImage;
	}


	public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment
                .getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),
                    image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null),
                    image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }

	/**
	 * 对字节数组字符串进行Base64解码并生成图片
	 * @param imgBase64Str Base64图片字符串
	 * @param basePath 保存图片路径
	 * @return 图片路径
	 */
	public static String GenerateImage(String imgBase64Str, String basePath) {
		// 图像数据为空
		if (imgBase64Str == null) {
			return "";
		}
		if(imgBase64Str.split(",").length>0){
			imgBase64Str = imgBase64Str.split(",")[1];
		}
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			// Base64解码
			byte[] b = decoder.decodeBuffer(imgBase64Str);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}

			File dir = new File(basePath);
			// 判断文件夹是否存在
			if (!dir.exists()) {
				dir.mkdirs();
			}
			// 生成jpeg图片
			String base64Name = UUID.randomUUID().toString();
			String picname = base64Name + ".png";
			String imgFilePath = basePath + "/" + picname;// 新生成的图片
			OutputStream out = new FileOutputStream(imgFilePath);
			out.write(b);
			out.flush();
			out.close();
			return picname;
		} catch (Exception e) {
			return "";
		}
	}
}
